#include <iostream>
#include <cstring>

#define MAC_ADDRESS_LENGTH 6
typedef unsigned char MAC_address[MAC_ADDRESS_LENGTH];

struct EthernetFrame
{
    MAC_address dest_mac;
    MAC_address src_mac;
    unsigned short type;
    char payload[];
};

MAC_address this_mac_address = {0x00, 0x50, 0x56, 0xC0, 0x00, 0x01};

int mac_address_match(const struct EthernetFrame *frame)
{
    bool is_broadcast = true;
    for (int i = 0; i < MAC_ADDRESS_LENGTH; i++)
    {
        if (frame->dest_mac[i] != 0xFF)
        {
            is_broadcast = false;
            break;
        }
    }
    if (is_broadcast)
        return 1;

    if ((frame->dest_mac[0] & 0x01) == 0x01)
    {
        return 1;
    }

    bool is_self = true;
    for (int i = 0; i < MAC_ADDRESS_LENGTH; i++)
    {
        if (frame->dest_mac[i] != this_mac_address[i])
        {
            is_self = false;
            break;
        }
    }
    return is_self ? 1 : 0;

    return 0;
}

//测试
int main()
{
    EthernetFrame broadcast_frame;
    memset(broadcast_frame.dest_mac, 0xFF, MAC_ADDRESS_LENGTH);
    memcpy(broadcast_frame.src_mac, this_mac_address, MAC_ADDRESS_LENGTH);
    broadcast_frame.type = 0x0800;

    std::cout << "Test broadcast frame: " << mac_address_match(&broadcast_frame) << std::endl;

    EthernetFrame multicast_frame;
    multicast_frame.dest_mac[0] = 0x01;
    memset(&multicast_frame.dest_mac[1], 0x00, MAC_ADDRESS_LENGTH - 1);
    memcpy(multicast_frame.src_mac, this_mac_address, MAC_ADDRESS_LENGTH);
    multicast_frame.type = 0x0800;

    std::cout << "Test multicast frame: " << mac_address_match(&multicast_frame) << std::endl;

    EthernetFrame self_frame;
    memcpy(self_frame.dest_mac, this_mac_address, MAC_ADDRESS_LENGTH);
    memcpy(self_frame.src_mac, this_mac_address, MAC_ADDRESS_LENGTH);
    self_frame.type = 0x0800;

    std::cout << "Test self frame: " << mac_address_match(&self_frame) << std::endl;

    EthernetFrame other_frame;
    other_frame.dest_mac[0] = 0x00;
    other_frame.dest_mac[1] = 0x00;
    other_frame.dest_mac[2] = 0x00;
    other_frame.dest_mac[3] = 0x00;
    other_frame.dest_mac[4] = 0x00;
    other_frame.dest_mac[5] = 0x02;
    memcpy(other_frame.src_mac, this_mac_address, MAC_ADDRESS_LENGTH);
    other_frame.type = 0x0800;

    std::cout << "Test wrong frame: " << mac_address_match(&other_frame) << std::endl;

    return 0;
}